home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / cc02.arc / CRC1.C < prev    next >
Text File  |  1986-03-14  |  6KB  |  133 lines

  1.  
  2. /******************************************************************************
  3. *                                                                             *
  4. *               Cyclic Redundancy Check (CRC) functions                       *
  5. *                                                                             *
  6. ******************************************************************************/
  7.  
  8. /*
  9. *   crc_clear:
  10. *       This function clears the CRC to zero. It should be called prior to
  11. *       the start of the processing of a block for both received messages,
  12. *       and messages to be transmitted.
  13. *
  14. *       Calling sequence:
  15. *
  16. *       short crc;
  17. *       crc = crc_clear();
  18. */
  19. short crc_clear()
  20. {
  21.         return(0);
  22. }
  23. /*
  24. *   crc_update:
  25. *       this function must be called once for each character which is
  26. *       to be included in the CRC for messages to be transmitted.
  27. *       This function is called once for each character which is included
  28. *       in the CRC of a received message, AND once for each of the two CRC
  29. *       characters at the end of the received message. If the resulting
  30. *       CRC is zero, then the message has been correctly received.
  31. *
  32. *   Calling sequence:
  33. *
  34. *       crc = crc_update(crc,next_char);
  35. */
  36. short crc_update(crc,crc_char)
  37. short crc;
  38. char crc_char;
  39. {
  40.         long x;
  41.         short i;
  42.  
  43. /* "x" will contain the character to be processed in bits 0-7 and the CRC    */
  44. /* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */
  45. /* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */
  46. /* used. ("x" is treated as though it is a 32 bit register).                 */
  47.         x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */
  48.  
  49. /* Repeat the following loop 8 times (for the 8 bits of the character).      */
  50.         for(i = 0;i < 8;i++)
  51.         {
  52.  
  53. /* Shift the high-order bit of the character into the low-order bit of the   */
  54. /* CRC, and shift the high-order bit of the CRC into bit 24.                 */
  55.                 x = x << 1;                        /* Shift "x" left one bit */
  56.  
  57. /* Test to see if the old high-order bit of the CRC was a 1.                 */
  58.                 if(x & 0x01000000)                     /* Test bit 24 of "x" */
  59.  
  60. /* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */
  61. /* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */
  62. /* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */
  63. /* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */
  64. /* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */
  65. /* and produce the same CRC that IBM uses for their synchronous transmission */
  66. /* protocols.                                                                */
  67.                         x = x ^ 0x01102100;     /* Exclusive-or "x" with a...*/
  68.                                               /* ...constant of hex 01102100 */
  69. /* And repeat 8 times.                                                       */
  70.         }                                               /* End of "for" loop */
  71.  
  72. /* Return the CRC as the 16 low-order bits of this function's value.         */
  73.         return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
  74.                                   /* ...shift the result 8 bits to the right */
  75.  
  76. }
  77. /*
  78. *   crc_finish:
  79. *       This function must be called once after all the characters in a block
  80. *       have been processed for a message which is to be TRANSMITTED. It
  81. *       returns the calculated CRC bytes, which should be transmitted as the
  82. *       two characters following the block. The first of these 2 bytes
  83. *       must be taken from the high-order byte of the CRC, and the second
  84. *       must be taken from the low-order byte of the CRC. This routine is NOT
  85. *       called for a message which has been RECEIVED.
  86. *
  87. *   Calling sequence:
  88. *
  89. *       crc = crc_finish(crc);
  90. */
  91. short crc_finish(crc)
  92. short crc;
  93. {
  94. /* Call crc_update twice, passing it a character of hex 00 each time, to     */
  95. /* flush out the last 16 bits from the CRC calculation, and return the       */
  96. /* result as the value of this function.                                     */
  97.         return(crc_update(crc_update(crc,'\0'),'\0'));
  98.  
  99. }
  100.  
  101. /*
  102. * This is a sample of the use of the CRC functions, which calculates the
  103. * CRC for a 1-character message block, and then passes the resulting CRC back
  104. * into the CRC functions to see if the "received" 1-character message and CRC
  105. * are correct.
  106. */
  107. main()
  108. {
  109.  
  110.         short crc;                                     /* The calculated CRC */
  111.         char crc_char;                            /* The 1-character message */
  112.         char x, y;            /* 2 places to hold the 2 "received" CRC bytes */
  113.  
  114.         crc_char = 'A';                    /* Define the 1-character message */
  115.         crc = crc_clear();      /* Reset the CRC to "transmit" a new message */
  116.         crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  117.                                    /* ...(and only) character of the message */
  118.         crc = crc_finish(crc);        /* Finish the transmission calculation */
  119.         x = (char)((crc & 0xff00) >> 8);  /* Extract the high-order CRC byte */
  120.         y = (char)(crc & 0x00ff);          /* And extract the low-order byte */
  121.         printf("%04x\n",crc);                           /* Print the results */
  122.  
  123.         crc = crc_clear();                 /* Prepare to "receive" a message */
  124.         crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  125.                                    /* ...(and only) character of the message */
  126.         crc = crc_update(crc,x);     /* Pass both bytes of the "received"... */
  127.         crc = crc_update(crc,y);           /* ...CRC through crc_update, too */
  128.         printf("%04x\n",crc);    /* If the result was 0, then the message... */
  129.                                             /* ...was received without error */
  130.  
  131. }
  132.  
  133.